<?php

namespace Parse;

abstract class Parser
{
    public $parsers;
    public $callback;

    abstract public function defaultCallback();

    public function __construct($callback)
    {
        if ($callback === null) {
            $callback = array($this, "defaultCallback");
        }
        if (!is_callable($callback)) {
            throw new ParseException("Callback must be a callable function, not "
                            . var_export($callback, true));
        }
        $this->callback = $callback;

        if ($this->parsers === null) {
            $this->parsers = array();
        }
    }

    public function match($string)
    {
        $matches = $this->matchProcedure($string);
        return array(
        "match" => call_user_func_array(
            $this->callback,
            $matches["matches"]
        ),
        "rest" => $matches["rest"]);
    }

    public function parse($string)
    {
        $match = $this->match($string);
        if (strlen($match["rest"]) > 0) {
            throw new ParseException("Parse incomplete");
        }
        return $match["match"];
    }

    abstract public function matchProcedure($string);
}
